#ifdef IMAM_COMMS
#include "SDK30.H"
#include "linklayer.h"
#include <del_types.h>
//#include <definekey.h>
#include <fm_proto.h>
#include <fm_hmiservice.h>
#include <fm_comms.h> 
#include <fm_userinterface.h>
#include <fm_genpinpad.h>
#include <cmm_ssl.h>

#ifndef __USE_DEL_INTERFACE__
#include <TlvTree.h>
#endif

extern int GET_CHAR(void);
extern uint8 pp_get_key(uint32 timeout);

#define Alarm(x) pp_beep(x)

#define nvmGetPabx() ReadSelectedFile(SELECTED_PABX)
#define  nvmAPNGet() ReadSelectedFile (SELECTED_APN)
#define nvmUserNameGet() ReadSelectedFile(SELECTED_USR)
#define nvmPasswordGet(void) ReadSelectedFile(SELECTED_PASS)



#define __TEST_COMM_RX__



#else
#include <incs.h>
#endif

#ifdef IMAM_COMMS

#define MDMCFG_FILE_NAME	"/HOST/MDMSTRING.CFG"

#define MAX_COM	5
#define DEFAULT_INIT_STRING_EXTERNAL	"AT&FE0"
#define DEFAULT_INIT_STRING_ASYNC		"ATZE0"

#define DEFAULT_INIT_STRING_SYNC		 "ATF4S144=16$M249$M251\rATS7=20"
//#define DEFAULT_INIT_STRING_SYNC		 "ATF5S144=16$M249$M251\rATS7=20"
//#define DEFAULT_INIT_STRING_SYNC		"ATX3;S144=16F4$M251$M249"	//original 1
//#define DEFAULT_INIT_STRING_SYNC		"ATF0;S7=200;S11=100;S37=0;S144=16"	//original 2

#define DEFAULT_PHONE_NUMBER_ASYNC		"607"
#define DEFAULT_PHONE_NUMBER_SYNC		"607"			// NAC development
#define DEFAULT_LOGIN					"wap"		// Telkomsel GPRS
#define DEFAULT_PASSWORD				"wap123"
#define DEFAULT_HOST_NAME_PPP			"192.168.0.1"
#define DEFAULT_PORT_PPP				80
#define DEFAULT_HOST_NAME_ETHERNET		"192.168.0.1"
#define DEFAULT_PORT_ETHERNET			88

#define MODE_NONE				0
#define MODE_SEND				1
#define MODE_ECHO				2
#define MODE_DOWNLOAD_HTTP		3
#define MODE_GREEK_HOST			4

#define PROTOCOLE_STACK_SIZE    1024/2
static unsigned long *protocole_stack[PROTOCOLE_STACK_SIZE];

typedef struct{	
	T__LL_CONFIGURATION CurrentConfig;
	LL_HANDLE hSession;
} FM_COM;

static FM_COM cominfo[MAX_COM];

//#ifdef __TEST_SEC_DIAL__
static uint16 cmmMode;
static uint8 DialPrimary;
//#endif
static cmmResult_t cmmRetVal;
static int retvalini;

/*
//aan, 17 Desember 2007
uint8 GetStringInitModem(const char * InitString)
{
	char tmpBuf [LL_MODEM_L_INIT_STRING_MAX+1];
	FMFILE * mdmFile;
	uint8 status = 0;
	int16 charRead = 0;
	
	if((mdmFile= FM_fopen(MDMCFG_FILE_NAME, "r"))==0)
		return status;//nu such file use default setting

	memset(tmpBuf,0,sizeof(tmpBuf));
	if((charRead=FM_fread((char*)tmpBuf, 1, LL_MODEM_L_INIT_STRING_MAX, mdmFile))<0)
		status = 0;//read err, i don't know why
	else
		status = 1;//successful read

	tmpBuf[0]=0x00;//remove the quote
	tmpBuf[charRead-1]=0x00;//remove the quote
	
	strcpy((char*)InitString, (char*)&tmpBuf[1]);
	
	FM_fclose(mdmFile);
	return status;
}
*/
void InitClearHandle(void)
{
	unsigned long i;
	for (i=0;i<MAX_COM;i++)
	{
		if (cominfo[i].hSession)
			LL_Disconnect(cominfo[i].hSession);
			
		cominfo[i].hSession=NULL;	
	}
}

void InitDefaultConfig(void)
{
	int i;

	//aan
	//memset((byte*)&cominfo, 0x00, sizeof(cominfo));

	for(i=0;i<MAX_COM;i++)
	{
	
	memset(&cominfo[i].CurrentConfig, 0, sizeof(cominfo[i].CurrentConfig));

	//cominfo[i].CurrentConfig.m_nLink = LL_PHYSICAL_V_COM0;
	cominfo[i].CurrentConfig.m_nLink = LL_PHYSICAL_V_MODEM;
	//cominfo[i].CurrentConfig.m_nLink = LL_PHYSICAL_V_ETHERNET;

	cominfo[i].CurrentConfig.m_nBaudrate = LL_PHYSICAL_V_BAUDRATE_9600;
	cominfo[i].CurrentConfig.m_nBitsPerByte = LL_PHYSICAL_V_8_BITS;
	cominfo[i].CurrentConfig.m_nStopBits = LL_PHYSICAL_V_1_STOP;
	cominfo[i].CurrentConfig.m_nParity = LL_PHYSICAL_V_NO_PARITY;
	cominfo[i].CurrentConfig.m_nFlowCtrl = LL_PHYSICAL_V_NO_FLOW_CTRL;

	//cominfo[i].CurrentConfig.m_bUseModem = FALSE;
	cominfo[i].CurrentConfig.m_bUseModem = TRUE;
	cominfo[i].CurrentConfig.m_nModemCmdTerminator = LL_MODEM_V_CMD_TERMINATOR_CR;
	strcpy(cominfo[i].CurrentConfig.m_szInitString, DEFAULT_INIT_STRING_ASYNC);
	strcpy(cominfo[i].CurrentConfig.m_szPhoneNumber, DEFAULT_PHONE_NUMBER_ASYNC);
	
	cominfo[i].CurrentConfig.m_bUseHdlc = FALSE;

	cominfo[i].CurrentConfig.m_bUsePpp = FALSE;
	strcpy(cominfo[i].CurrentConfig.m_szLogin, DEFAULT_LOGIN);
	strcpy(cominfo[i].CurrentConfig.m_szPassword, DEFAULT_PASSWORD);

	cominfo[i].CurrentConfig.m_bUseTcpIp = FALSE;
	strcpy(cominfo[i].CurrentConfig.m_szHostName, DEFAULT_HOST_NAME_ETHERNET);
	cominfo[i].CurrentConfig.m_nPort = DEFAULT_PORT_ETHERNET;


	cominfo[i].CurrentConfig.m_nTestMode = MODE_SEND;

	}
}

long getcombufempty(void)
{
	unsigned long i;	 

	for (i=0;i<MAX_COM;i++)
	{
		if (cominfo[i].hSession==NULL)
			return i;
	}
	return -1;
}

static int ConfigureTCP(INIT_COMMS_PARAMS *icp, int idx, int isprim)
{

   	

	cominfo[idx].CurrentConfig.m_nLink = LL_PHYSICAL_V_ETHERNET;

	cominfo[idx].CurrentConfig.m_bUseTcpIp = TRUE;
	if (isprim)
	{
		//strcpy(cominfo[idx].CurrentConfig.m_szHostName, icp->cmm.IP.ipAddrPri);
		//cominfo[idx].CurrentConfig.m_szHostName[4]='\0';
		sprintf(cominfo[idx].CurrentConfig.m_szHostName,"%d.%d.%d.%d",
										icp->cmm.IP.ipAddrPri[0],
										icp->cmm.IP.ipAddrPri[1],
										icp->cmm.IP.ipAddrPri[2],
										icp->cmm.IP.ipAddrPri[3]);
		cominfo[idx].CurrentConfig.m_nPort = icp->cmm.IP.portNumPri;
		_trace("1%s ",cominfo[idx].CurrentConfig.m_szHostName);
		_trace("1port%d ",cominfo[idx].CurrentConfig.m_nPort);
	}
	else
	{
		//strcpy(cominfo[idx].CurrentConfig.m_szHostName, icp->cmm.IP.ipAddrSec);
		//cominfo[idx].CurrentConfig.m_szHostName[4]='\0';
		sprintf(cominfo[idx].CurrentConfig.m_szHostName,"%d.%d.%d.%d",
										icp->cmm.IP.ipAddrSec[0],
										icp->cmm.IP.ipAddrSec[1],
										icp->cmm.IP.ipAddrSec[2],
										icp->cmm.IP.ipAddrSec[3]);
		cominfo[idx].CurrentConfig.m_nPort = icp->cmm.IP.portNumSec;
		_trace("2%s ",cominfo[idx].CurrentConfig.m_szHostName);
		_trace("1port%d ",cominfo[idx].CurrentConfig.m_nPort);

	}

	cominfo[idx].CurrentConfig.m_bUseModem = FALSE;
	cominfo[idx].CurrentConfig.m_bUseHdlc = FALSE;
	cominfo[idx].CurrentConfig.m_bUsePpp = FALSE;

	if (cominfo[idx].CurrentConfig.m_nTestMode == MODE_DOWNLOAD_HTTP)
		cominfo[idx].CurrentConfig.m_nTestMode = MODE_NONE;

	return 0;
}

static int ConfigureModem(INIT_COMMS_PARAMS *icp, int idx, int isprim)
{
		//aan, 16 Juli 2007
	char pabx[17];
	memset(pabx,0x00,sizeof(pabx));
       strcpy(pabx, (char *)nvmGetPabx());// imam 
	
	cominfo[idx].CurrentConfig.m_nLink = LL_PHYSICAL_V_MODEM;

	cominfo[idx].CurrentConfig.m_bUseModem = TRUE;
	cominfo[idx].CurrentConfig.m_nModemCmdTerminator = LL_MODEM_V_CMD_TERMINATOR_CR;
	strcpy(cominfo[idx].CurrentConfig.m_szInitString, DEFAULT_INIT_STRING_ASYNC);

	if(pabx[0] != 0x00)//aan, 16 Juli 2007
		{
	       strcat(cominfo[idx].CurrentConfig.m_szPhoneNumber, (char *)nvmGetPabx());// imam 
		strcat(cominfo[idx].CurrentConfig.m_szPhoneNumber, ",");
		}
	
	if (isprim)
		strcpy(cominfo[idx].CurrentConfig.m_szPhoneNumber, icp->cmm.Dial.pri_num);//DEFAULT_PHONE_NUMBER_SYNC);
	else	
		strcpy(cominfo[idx].CurrentConfig.m_szPhoneNumber, icp->cmm.Dial.sec_num);//DEFAULT_PHONE_NUMBER_SYNC);
		
	cominfo[idx].CurrentConfig.m_bUseHdlc = FALSE;
	cominfo[idx].CurrentConfig.m_bUsePpp = FALSE;
	cominfo[idx].CurrentConfig.m_bUseTcpIp = FALSE;

	cominfo[idx].CurrentConfig.m_nConnectionTimeout = (int)icp->connect_timeout;

	if (cominfo[idx].CurrentConfig.m_nTestMode == MODE_DOWNLOAD_HTTP)
		cominfo[idx].CurrentConfig.m_nTestMode = MODE_NONE;

	return 0;
}

static int ConfigurePPP(INIT_COMMS_PARAMS *icp, int idx, int isprim)
{
	cominfo[idx].CurrentConfig.m_nLink=LL_PHYSICAL_V_MODEM;	
	cominfo[idx].CurrentConfig.m_bUseModem = TRUE;
	cominfo[idx].CurrentConfig.m_nModemCmdTerminator = LL_MODEM_V_CMD_TERMINATOR_CR;

	strcpy(cominfo[idx].CurrentConfig.m_szInitString, DEFAULT_INIT_STRING_ASYNC);
	if (isprim)
		strcpy(cominfo[idx].CurrentConfig.m_szPhoneNumber,  icp->cmm.Dial.pri_num);
	else
		strcpy(cominfo[idx].CurrentConfig.m_szPhoneNumber,  icp->cmm.Dial.sec_num);
	
	cominfo[idx].CurrentConfig.m_bUseHdlc = FALSE;
	cominfo[idx].CurrentConfig.m_bUsePpp = TRUE;
	strcpy(cominfo[idx].CurrentConfig.m_szLogin, icp->cmm.IP.username);
	strcpy(cominfo[idx].CurrentConfig.m_szPassword, icp->cmm.IP.password);

	cominfo[idx].CurrentConfig.m_bUseTcpIp = TRUE;
	strcpy(cominfo[idx].CurrentConfig.m_szHostName, icp->cmm.IP.ipAddrPri);
	cominfo[idx].CurrentConfig.m_nPort = icp->cmm.IP.portNumPri;
	return 0;
}

static int ConfigureGPRS(INIT_COMMS_PARAMS *icp, int idx, int isprim)
{
	cominfo[idx].CurrentConfig.m_nLink=LL_PHYSICAL_V_GPRS;	
	
	strcpy(cominfo[idx].CurrentConfig.m_szLogin, icp->cmm.IP.username);
	strcpy(cominfo[idx].CurrentConfig.m_szPassword, icp->cmm.IP.password);
	
	cominfo[idx].CurrentConfig.m_bUseGprs = TRUE;
	cominfo[idx].CurrentConfig.m_bUseModem=FALSE;
	cominfo[idx].CurrentConfig.m_bUseHdlc = FALSE;
	cominfo[idx].CurrentConfig.m_bUsePpp = FALSE;
	
	cominfo[idx].CurrentConfig.m_bUseTcpIp = TRUE;

//	cominfo[idx].CurrentConfig.m_nConnectionTimeout = (int)icp->connect_timeout;

	return 0;
}

static int ConfigureHdlc(INIT_COMMS_PARAMS *icp, int idx,  int isprim)
{
	//aan, 16 Juli 2007
	uint8 iTes;
	char pabx[17];
	memset(pabx,0x00,sizeof(pabx));
	_trace("configure hdlc");
	 strcpy(pabx, (char *) nvmGetPabx());// imam 
	
	cominfo[idx].CurrentConfig.m_nLink = LL_PHYSICAL_V_MODEM;

	cominfo[idx].CurrentConfig.m_bUseModem = TRUE;
	cominfo[idx].CurrentConfig.m_nModemCmdTerminator = LL_MODEM_V_CMD_TERMINATOR_CR;
//	if(GetStringInitModem(cominfo[idx].CurrentConfig.m_szInitString)==0)//if mdminit file doesn't exist use the default init string
	strcpy(cominfo[idx].CurrentConfig.m_szInitString, DEFAULT_INIT_STRING_SYNC);
	_trace("Default Init String : (%s)", cominfo[idx].CurrentConfig.m_szInitString);

//	memset(cominfo[idx].CurrentConfig.m_szPhoneNumber,0x00,LL_MODEM_L_PHONE_NUMBER_MAX + 1);
	strcpy(cominfo[idx].CurrentConfig.m_szPhoneNumber, "^" );
	
	if(pabx[0] != 0x00)//aan, 16 Juli 2007
		{
		strcat(cominfo[idx].CurrentConfig.m_szPhoneNumber, (char *)nvmGetPabx());// imam 
		strcat(cominfo[idx].CurrentConfig.m_szPhoneNumber, ",");
		}
	
	if (isprim)
		strcat(cominfo[idx].CurrentConfig.m_szPhoneNumber, icp->cmm.Dial.pri_num);
	else
		strcat(cominfo[idx].CurrentConfig.m_szPhoneNumber, icp->cmm.Dial.sec_num);

	for(iTes=0;iTes <(LL_MODEM_L_PHONE_NUMBER_MAX + 1);iTes++)
		{
		if(cominfo[idx].CurrentConfig.m_szPhoneNumber[iTes]==' ')
			{
//			cominfo[idx].CurrentConfig.m_szPhoneNumber[iTes++]='\n';
			cominfo[idx].CurrentConfig.m_szPhoneNumber[iTes]='\0';
			break;
			}
		}
	
	_trace("Prim Num : (%s)", cominfo[idx].CurrentConfig.m_szPhoneNumber);
	
	cominfo[idx].CurrentConfig.m_bUseHdlc = TRUE;
	cominfo[idx].CurrentConfig.m_bUsePpp = FALSE;
	cominfo[idx].CurrentConfig.m_bUseTcpIp = FALSE;

//aan
	cominfo[idx].CurrentConfig.m_nConnectionTimeout = (int)icp->connect_timeout;
//aan

	if (cominfo[idx].CurrentConfig.m_nTestMode == MODE_DOWNLOAD_HTTP)
		cominfo[idx].CurrentConfig.m_nTestMode = MODE_NONE;

	return 0;
}

static int ConfigureComUSB(INIT_COMMS_PARAMS *icp, int idx, int isprim)
{
	if (isprim)
		cominfo[idx].CurrentConfig.m_nLink = LL_PHYSICAL_V_USB;//LL_PHYSICAL_V_COM0;//LL_PHYSICAL_V_USB;//
	else
		cominfo[idx].CurrentConfig.m_nLink = icp->cmm.RS232.comport;
		
	cominfo[idx].CurrentConfig.m_bUseModem = FALSE;
	cominfo[idx].CurrentConfig.m_bUseHdlc = FALSE;
	cominfo[idx].CurrentConfig.m_bUsePpp = FALSE;
	cominfo[idx].CurrentConfig.m_bUseTcpIp = FALSE;
	
	cominfo[idx].CurrentConfig.m_nBaudrate = icp->cmm.RS232.speed;//LL_PHYSICAL_V_BAUDRATE_115200;
	cominfo[idx].CurrentConfig.m_nBitsPerByte = icp->cmm.RS232.dataSize;//LL_PHYSICAL_V_8_BITS;
	cominfo[idx].CurrentConfig.m_nStopBits = icp->cmm.RS232.stopBits;//LL_PHYSICAL_V_1_STOP;
	cominfo[idx].CurrentConfig.m_nParity = icp->cmm.RS232.parity;//LL_PHYSICAL_V_NO_PARITY;
	cominfo[idx].CurrentConfig.m_nFlowCtrl = LL_PHYSICAL_V_NO_FLOW_CTRL;
	//fitra
	if (cominfo[idx].CurrentConfig.m_nTestMode == MODE_DOWNLOAD_HTTP)
		cominfo[idx].CurrentConfig.m_nTestMode = MODE_NONE;
	//cominfo[idx].CurrentConfig.m_nTestMode=MODE_SEND;
	return 0;
}

int Connect( _DEL_* i_pDel , T__LL_CONFIGURATION *CurrentConfig)
{
	_DEL_ Configuration;
	unsigned char PhysicalConfig[256];
	unsigned char DataLinkConfig[256];
	unsigned char TransportConfig[256];
	int nOffset;

	// Needed to call the link layer
	memset( &Configuration, 0x00, sizeof(Configuration) );

		// Physical layer parameters
	nOffset = 0;
	PhysicalConfig[nOffset + 0] = LL_PHYSICAL_T_LINK;
	PhysicalConfig[nOffset + 1] = LL_PHYSICAL_L_LINK;
	PhysicalConfig[nOffset + 2] = (unsigned char)CurrentConfig->m_nLink;
	nOffset += 2 + PhysicalConfig[nOffset + 1];

	if(!CurrentConfig->m_bUseGprs)
		{
	PhysicalConfig[nOffset + 0] = LL_PHYSICAL_T_BAUDRATE;
	PhysicalConfig[nOffset + 1] = LL_PHYSICAL_L_BAUDRATE;
	PhysicalConfig[nOffset + 2] = (unsigned char)(CurrentConfig->m_nBaudrate & 0xff);
	PhysicalConfig[nOffset + 3] = (unsigned char)((CurrentConfig->m_nBaudrate >> 8) & 0xff);
	PhysicalConfig[nOffset + 4] = (unsigned char)((CurrentConfig->m_nBaudrate >> 16) & 0xff);
	PhysicalConfig[nOffset + 5] = (unsigned char)((CurrentConfig->m_nBaudrate >> 24) & 0xff);
	nOffset += 2 + PhysicalConfig[nOffset + 1];
		}

/*	CurrentConfig.m_nBitsPerByte = LL_PHYSICAL_V_8_BITS;
	CurrentConfig.m_nStopBits = LL_PHYSICAL_V_1_STOP;
	CurrentConfig.m_nParity = LL_PHYSICAL_V_NO_PARITY;
	CurrentConfig.m_nFlowCtrl = LL_PHYSICAL_V_NO_FLOW_CTRL;
*/

	if (CurrentConfig->m_bUseGsm)
	{
		// Modulation.
		PhysicalConfig[nOffset + 0] = LL_GSM_T_MODULATION;
		PhysicalConfig[nOffset + 1] = LL_GSM_L_MODULATION;
		PhysicalConfig[nOffset + 2] = (unsigned char)(CurrentConfig->m_nGsmModulation & 0xff);
		PhysicalConfig[nOffset + 3] = (unsigned char)((CurrentConfig->m_nGsmModulation >> 8) & 0xff);
		PhysicalConfig[nOffset + 4] = (unsigned char)((CurrentConfig->m_nGsmModulation >> 16) & 0xff);
		PhysicalConfig[nOffset + 5] = (unsigned char)((CurrentConfig->m_nGsmModulation >> 24) & 0xff);
		nOffset += 2 + PhysicalConfig[nOffset + 1];

		// Mode (RLP/Transparent).
		PhysicalConfig[nOffset + 0] = LL_GSM_T_MODE;
		PhysicalConfig[nOffset + 1] = LL_GSM_L_MODE;
		PhysicalConfig[nOffset + 2] = (unsigned char)(CurrentConfig->m_nGsmMode & 0xff);
		nOffset += 2 + PhysicalConfig[nOffset + 1];
	
		// Connection timeout.
		PhysicalConfig[nOffset + 0] = LL_GSM_T_CONNECTION_TIMEOUT;
		PhysicalConfig[nOffset + 1] = LL_GSM_L_CONNECTION_TIMEOUT;
		PhysicalConfig[nOffset + 2] = (unsigned char)(CurrentConfig->m_nConnectionTimeout & 0xff);
		PhysicalConfig[nOffset + 3] = (unsigned char)((CurrentConfig->m_nConnectionTimeout >> 8) & 0xff);
		PhysicalConfig[nOffset + 4] = (unsigned char)((CurrentConfig->m_nConnectionTimeout >> 16) & 0xff);
		PhysicalConfig[nOffset + 5] = (unsigned char)((CurrentConfig->m_nConnectionTimeout >> 24) & 0xff);
		nOffset += 2 + PhysicalConfig[nOffset + 1];

		// Phone number.
		PhysicalConfig[nOffset + 0] = LL_MODEM_T_PHONE_NUMBER;
		PhysicalConfig[nOffset + 1] = (unsigned char)strlen(CurrentConfig->m_szPhoneNumber);
		strcpy((char*)&PhysicalConfig[nOffset + 2], CurrentConfig->m_szPhoneNumber);
		nOffset += 2 + PhysicalConfig[nOffset + 1];
	}

	if (CurrentConfig->m_bUseModem)
	{
		PhysicalConfig[nOffset + 0] = LL_MODEM_T_CMD_TERMINATOR;
		PhysicalConfig[nOffset + 1] = LL_MODEM_L_CMD_TERMINATOR;
		PhysicalConfig[nOffset + 2] = (unsigned char)CurrentConfig->m_nModemCmdTerminator;
		nOffset += 2 + PhysicalConfig[nOffset + 1];

		// Connection timeout.//aan nambah
		PhysicalConfig[nOffset + 0] = LL_MODEM_T_DIAL_TIMEOUT;
		PhysicalConfig[nOffset + 1] = LL_MODEM_L_DIAL_TIMEOUT;
		PhysicalConfig[nOffset + 2] = (unsigned char)(CurrentConfig->m_nConnectionTimeout & 0xff);
		PhysicalConfig[nOffset + 3] = (unsigned char)((CurrentConfig->m_nConnectionTimeout >> 8) & 0xff);
		PhysicalConfig[nOffset + 4] = (unsigned char)((CurrentConfig->m_nConnectionTimeout >> 16) & 0xff);
		PhysicalConfig[nOffset + 5] = (unsigned char)((CurrentConfig->m_nConnectionTimeout >> 24) & 0xff);
		nOffset += 2 + PhysicalConfig[nOffset + 1];

		PhysicalConfig[nOffset + 0] = LL_MODEM_T_INIT_STRING;
		PhysicalConfig[nOffset + 1] = (unsigned char)strlen(CurrentConfig->m_szInitString);
		strcpy((char*)&PhysicalConfig[nOffset + 2], CurrentConfig->m_szInitString);
		nOffset += 2 + PhysicalConfig[nOffset + 1];

		PhysicalConfig[nOffset + 0] = LL_MODEM_T_PHONE_NUMBER;
		PhysicalConfig[nOffset + 1] = (unsigned char)strlen(CurrentConfig->m_szPhoneNumber);
		strcpy((char*)&PhysicalConfig[nOffset + 2], CurrentConfig->m_szPhoneNumber);
		nOffset += 2 + PhysicalConfig[nOffset + 1];
	}

	Configuration.list[Configuration.count].tag = LL_TAG_PHYSICAL_LAYER_CONFIG;
	Configuration.list[Configuration.count].length = nOffset;
	memcpy(Configuration.list[Configuration.count].ptValue, &PhysicalConfig, nOffset);
	Configuration.count++;

	// Data link layer parameters
	// HDLC
	nOffset = 0;
	if (CurrentConfig->m_bUseHdlc)
	{
		DataLinkConfig[nOffset + 0] = LL_DATA_LINK_T_PROTOCOL;
		DataLinkConfig[nOffset + 1] = LL_DATA_LINK_L_PROTOCOL;
		DataLinkConfig[nOffset + 2] = LL_DATA_LINK_V_HDLC;
		nOffset += 2 + DataLinkConfig[nOffset + 1];

		DataLinkConfig[nOffset + 0] = LL_HDLC_T_MIN_RESEND_REQUESTS;
		DataLinkConfig[nOffset + 1] = LL_HDLC_L_MIN_RESEND_REQUESTS;
		DataLinkConfig[nOffset + 2] = 2;
		nOffset += 2 + DataLinkConfig[nOffset + 1];
	}

	// PPP
	if (CurrentConfig->m_bUsePpp)
	{
		DataLinkConfig[nOffset + 0] = LL_DATA_LINK_T_PROTOCOL;
		DataLinkConfig[nOffset + 1] = LL_DATA_LINK_L_PROTOCOL;
		DataLinkConfig[nOffset + 2] = LL_DATA_LINK_V_PPP;
		nOffset += 2 + DataLinkConfig[nOffset + 1];

		DataLinkConfig[nOffset + 0] = LL_PPP_T_LOGIN;
		DataLinkConfig[nOffset + 1] = (unsigned char)strlen(CurrentConfig->m_szLogin);
		strcpy((char*)&DataLinkConfig[nOffset + 2], CurrentConfig->m_szLogin);
		nOffset += 2 + DataLinkConfig[nOffset + 1];

		DataLinkConfig[nOffset + 0] = LL_PPP_T_PASSWORD;
		DataLinkConfig[nOffset + 1] = (unsigned char)strlen(CurrentConfig->m_szPassword);
		strcpy((char*)&DataLinkConfig[nOffset + 2], CurrentConfig->m_szPassword);
		nOffset += 2 + DataLinkConfig[nOffset + 1];
	}

	if (nOffset > 0)
	{
		Configuration.list[Configuration.count].tag = LL_TAG_DATA_LINK_LAYER_CONFIG;
		Configuration.list[Configuration.count].length = nOffset;
		memcpy(Configuration.list[Configuration.count].ptValue, &DataLinkConfig, nOffset);
		Configuration.count++;
	}

	// Transport layer parameters
	// TCP/IP
	nOffset = 0;
	if (CurrentConfig->m_bUseTcpIp)
	{
		TransportConfig[nOffset + 0] = LL_TRANSPORT_T_PROTOCOL;
		TransportConfig[nOffset + 1] = LL_TRANSPORT_L_PROTOCOL;
		TransportConfig[nOffset + 2] = LL_TRANSPORT_V_TCPIP;
		nOffset += 2 + TransportConfig[nOffset + 1];

		TransportConfig[nOffset + 0] = LL_TCPIP_T_HOST_NAME;
		TransportConfig[nOffset + 1] = (unsigned char)strlen(CurrentConfig->m_szHostName);
		strcpy((char*)&TransportConfig[nOffset + 2], CurrentConfig->m_szHostName);
		nOffset += 2 + TransportConfig[nOffset + 1];

		TransportConfig[nOffset + 0] = LL_TCPIP_T_PORT;
		TransportConfig[nOffset + 1] = LL_TCPIP_L_PORT;
		TransportConfig[nOffset + 2] = (unsigned char)(CurrentConfig->m_nPort & 0xff);
		TransportConfig[nOffset + 3] = (unsigned char)((CurrentConfig->m_nPort >> 8) & 0xff);
		TransportConfig[nOffset + 4] = (unsigned char)((CurrentConfig->m_nPort >> 16) & 0xff);
		TransportConfig[nOffset + 5] = (unsigned char)((CurrentConfig->m_nPort >> 24) & 0xff);
		nOffset += 2 + TransportConfig[nOffset + 1];

		TransportConfig[nOffset + 0] = LL_TCPIP_T_CONNECT_TIMEOUT;
		TransportConfig[nOffset + 1] = LL_TCPIP_L_CONNECT_TIMEOUT;
		TransportConfig[nOffset + 2] = (unsigned char)(CurrentConfig->m_nConnectionTimeout & 0xff);
		TransportConfig[nOffset + 3] = (unsigned char)((CurrentConfig->m_nConnectionTimeout >> 8) & 0xff);
		TransportConfig[nOffset + 4] = (unsigned char)((CurrentConfig->m_nConnectionTimeout >> 16) & 0xff);
		TransportConfig[nOffset + 5] = (unsigned char)((CurrentConfig->m_nConnectionTimeout >> 24) & 0xff);
		nOffset += 2 + TransportConfig[nOffset + 1];
	}

	if (nOffset > 0)
	{
		Configuration.list[Configuration.count].tag = LL_TAG_TRANSPORT_LAYER_CONFIG;
		Configuration.list[Configuration.count].length = nOffset;
		memcpy(Configuration.list[Configuration.count].ptValue, &TransportConfig, nOffset);
		Configuration.count++;
	}

	memcpy( i_pDel, &Configuration, sizeof(_DEL_) );
	return TRUE;
}

#ifndef WIN32
//aan
/*** Public ***/
//static 
static uint32 cmmIndx;
static t_topstack * ThreadHandle;//, gprsThreadHandle;
static short	MainTask;
static int		iThreadTerminate;//, gprsThreadTerminate;
static bits32 predialState;

//cmmResult_t cmmRetVal;
/************/

cmmResult_t cmmConnect (void)
{
	int conRetval=0;	

	//cmmResult_t conStatus;

	if (cominfo[cmmIndx].hSession)
	{		
		pp_ttestall(0, 30);//wait forever till the thread kill
		conRetval=LL_Connect(cominfo[cmmIndx].hSession);

	//	_trace("cmm Connect %d",conRetval);
		 retvalini=conRetval;
		//if (conRetval)
	 	cmmRetVal=cmmLastErr(conRetval);

		if(predialState)
		{
		iThreadTerminate = TRUE;
		SignalEvent(MainTask, 30);
		pp_ttestall(0, 0);//wait forever till the thread kill
		}

	
		return cmmRetVal;
	}
	else
		return cmmErrGeneral;

}

#ifdef _SSL_ENABLE_

int cmmSslConfigure(INIT_COMMS_PARAMS * icp, int isPrimary)
{
	char Temp[50] ;

	memset(Temp, 0x00, sizeof(Temp));

	if (isPrimary)
	{
		sprintf(Temp, "%d.%d.%d.%d", 	icp->cmm.IP.ipAddrPri[0],
									icp->cmm.IP.ipAddrPri[1],
									icp->cmm.IP.ipAddrPri[2],
									icp->cmm.IP.ipAddrPri[3]);
 
		SslConfigureHost(Temp, icp->cmm.IP.portNumPri);
	}
	else
	{
		sprintf(Temp, "%d.%d.%d.%d", 	icp->cmm.IP.ipAddrSec[0],
									icp->cmm.IP.ipAddrSec[1],
									icp->cmm.IP.ipAddrSec[2],
									icp->cmm.IP.ipAddrSec[3]);

		SslConfigureHost(Temp, icp->cmm.IP.portNumSec); 
	}

	return 0;	
}

cmmResult_t cmmSslConnect()
{
	// Set flag
	SslSetConnectingFlag(1);

	pp_ttestall(0, 30);

	// Connecting to host
	if(!SslConnect())
		cmmRetVal = cmmErrGeneral;
	else
		cmmRetVal = cmmSuccess;

	if(predialState)
	{
		iThreadTerminate = TRUE;

		// Signal main task
		SignalEvent(MainTask, 30);

		// Reset flag
		SslSetConnectingFlag(0);

		// Wait forever till the thread kill
		pp_ttestall(0, 0);
	}

	// Reset flag
	SslSetConnectingFlag(0);

	return cmmRetVal;
}

cmmResult_t  cmmSslEnd()
{	
	uint8 tforce=FALSE;

	_trace("nvmDisconnectAlgorithmGet");
	
	if (!iThreadTerminate)
	{
		 tforce = TRUE;
		 pp_ttestall(0, 50);

		SslDisconnect();
		
		_trace("SslDisconnect Done");
		
		iThreadTerminate=TRUE;
	}

	_trace("Kill Thread");
	killthread();
	_trace("Kill Thread Done");
	
	if (!tforce)
	{
		SslDisconnect();
	}

	return cmmSuccess;
}


int16 cmmSslSend(const uint8 * msg, size_t length)
{
	int bSend, n;
	uint16 tm;

	_trace("SSL Send");
	
	n = length;
	
	while (n > 0)
	{		
		bSend = SslSend(msg, n);

		if( bSend >= 0 )
			n -= bSend;
		else
			return cmmErrGeneral;
	
		tm = ttestall(KEYBOARD, 1);
		
		if (tm & KEYBOARD)
		{
			if (kbdRead() == (char)VK_CANCEL)
				return cmmErrUserCancel;
		}	
	}

	return cmmSuccess;
}

int16 cmmSslRecv(uint8* msg, uint16* length, size_t maxSize)
{
	int len;//uint16 len;

	*length = 0;
	
	len = SslReceive(msg, (int)maxSize);

	if(len == -1)
		return cmmErrUserTimeout;

	if(len < -1)
		return cmmErrGeneral;
		
	*length = (uint16)len;

	return cmmSuccess;
}

#endif

//aan
#endif // WIN32

#ifdef __USE_DEL_INTERFACE__
cmmResult_t cmmConfigure(T__LL_CONFIGURATION * cfg, LL_HANDLE * devH)
{
	int nError;
	_DEL_ pDel;
	
	Connect( &pDel, cfg);	
	
		nError = LL_Configure(devH,&pDel);// imam LL_Configure(devH,&pDel); 
//	if(nvmTMSDebugGet() || nvmFlagCommsDebugGet())
//		{
//		hex_dump("cmm \\ LL_conf", &nError, sizeof(int));
//		}
		
	if (nError != LL_ERROR_OK)
	{
		_trace("nError %d", nError);
		devH=NULL;
		return cmmErrInitFailed;
	}
	return cmmSuccess;
}
#else
// declare var



//#define cmmConfigure(LL_Config, LL_Session) tlvCmmConfigure((T__LL_CONFIGURATION *)LL_Config, (LL_HANDLE *) LL_Session)

cmmResult_t cmmConfigure ( T__LL_CONFIGURATION *CurrentConfig, LL_HANDLE * cmmSession )
{
	
	TLV_TREE_NODE hConfig=NULL;
	TLV_TREE_NODE hPhysicalConfig=NULL;
	TLV_TREE_NODE hDataLinkConfig=NULL;
	TLV_TREE_NODE hTransportConfig=NULL;
	int nError;
	
	// the MUST step, construct new TLV for Linklayer (since we would like to use linklayer)
	hConfig = TlvTree_New(LL_TAG_LINK_LAYER_CONFIG);
	if(hConfig == NULL)
		{
		return cmmErrInitFailed;
		}
	// ==========================================================================
	// add new sub TLV, if neccessary, in this case 1st set new sub TLV for physical layer
	// Physical layer parameters  
	hPhysicalConfig = TlvTree_AddChild(hConfig,                        
		                               LL_TAG_PHYSICAL_LAYER_CONFIG,  // TAG Physical layer parameters 
									   NULL,                          // VALUE (Null)
									   0);                            // LENGTH 0

	if(hPhysicalConfig == NULL)
		{
		TlvTree_Release(hConfig);
		return cmmErrInitFailed;
		}
	TlvTree_AddChildInteger(hPhysicalConfig, LL_PHYSICAL_T_LINK, (unsigned int)CurrentConfig->m_nLink, LL_PHYSICAL_L_LINK);

	
	if((CurrentConfig->m_nLink == LL_PHYSICAL_V_USB) || (CurrentConfig->m_nLink == LL_PHYSICAL_V_COM0) )
		{
		TlvTree_AddChildInteger(hPhysicalConfig, LL_PHYSICAL_T_BITS_PER_BYTE, (unsigned int)CurrentConfig->m_nBitsPerByte, LL_PHYSICAL_L_BITS_PER_BYTE);
//		cominfo[idx].CurrentConfig.m_nBitsPerByte = icp->cmm.RS232.dataSize;//LL_PHYSICAL_V_8_BITS;
		TlvTree_AddChildInteger(hPhysicalConfig, LL_PHYSICAL_T_STOP_BITS, (unsigned int)CurrentConfig->m_nStopBits,LL_PHYSICAL_L_STOP_BITS);
//		cominfo[idx].CurrentConfig.m_nStopBits = icp->cmm.RS232.stopBits;//LL_PHYSICAL_V_1_STOP;
		TlvTree_AddChildInteger(hPhysicalConfig, LL_PHYSICAL_T_PARITY, (unsigned int)CurrentConfig->m_nParity, LL_PHYSICAL_L_PARITY);
//		cominfo[idx].CurrentConfig.m_nParity = icp->cmm.RS232.parity;//LL_PHYSICAL_V_NO_PARITY;
		TlvTree_AddChildInteger(hPhysicalConfig, LL_PHYSICAL_T_FLOW_CTRL, (unsigned int)CurrentConfig->m_nFlowCtrl, LL_PHYSICAL_L_FLOW_CTRL);
//		cominfo[idx].CurrentConfig.m_nFlowCtrl = LL_PHYSICAL_V_NO_FLOW_CTRL;
		}

	if(!CurrentConfig->m_bUseGprs)
		{
		if(CurrentConfig->m_nLink == LL_PHYSICAL_V_USB)
			{
			long lBaudrate;
			unsigned int iBaudrate;
			
			lBaudrate = LL_PHYSICAL_V_BAUDRATE_115200;
			iBaudrate = LL_PHYSICAL_V_BAUDRATE_115200;
			
			TlvTree_AddChildInteger(hPhysicalConfig, LL_PHYSICAL_T_BAUDRATE, iBaudrate, LL_PHYSICAL_L_BAUDRATE);
			}
		else
			{
			TlvTree_AddChildInteger(hPhysicalConfig, LL_PHYSICAL_T_BAUDRATE, CurrentConfig->m_nBaudrate, LL_PHYSICAL_L_BAUDRATE);
			}
		}


	if(CurrentConfig->m_bUseGsm)
		{
		TlvTree_AddChildInteger(hPhysicalConfig, LL_GSM_T_MODULATION, CurrentConfig->m_nGsmModulation, LL_GSM_L_MODULATION);
		TlvTree_AddChildInteger(hPhysicalConfig, LL_GSM_T_MODE, CurrentConfig->m_nGsmMode, LL_GSM_L_MODE);
		TlvTree_AddChildInteger(hPhysicalConfig, LL_GSM_T_CONNECTION_TIMEOUT, CurrentConfig->m_nConnectionTimeout, LL_GSM_L_CONNECTION_TIMEOUT);
		}

	if(CurrentConfig->m_bUseModem)
		{
		TlvTree_AddChildInteger(hPhysicalConfig, LL_MODEM_T_CMD_TERMINATOR , CurrentConfig->m_nModemCmdTerminator, LL_MODEM_L_CMD_TERMINATOR);
		TlvTree_AddChildInteger(hPhysicalConfig, LL_MODEM_T_DIAL_TIMEOUT, CurrentConfig->m_nConnectionTimeout, LL_MODEM_L_DIAL_TIMEOUT);
		TlvTree_AddChildString(hPhysicalConfig, LL_MODEM_T_INIT_STRING, CurrentConfig->m_szInitString);
		}

	if( (CurrentConfig->m_bUseGsm) || (CurrentConfig->m_bUseModem) )
		TlvTree_AddChildString(hPhysicalConfig, LL_MODEM_T_PHONE_NUMBER , CurrentConfig->m_szPhoneNumber);

	//===========================================================================
	// 2nd set data link layer
	if( (CurrentConfig->m_bUseHdlc) || (CurrentConfig->m_bUsePpp) )
		{
		hDataLinkConfig = TlvTree_AddChild(hConfig,                        
										   LL_TAG_DATA_LINK_LAYER_CONFIG,   // TAG Data link layer parameters 
										   NULL,                            // VALUE (Null)
										   0);                              // LENGTH 0

		if(hDataLinkConfig == NULL)
			{
			TlvTree_Release(hConfig);
			return cmmErrInitFailed;
			}
		
		if(CurrentConfig->m_bUseHdlc)
			{
			TlvTree_AddChildInteger(hDataLinkConfig, LL_DATA_LINK_T_PROTOCOL, LL_DATA_LINK_V_HDLC, LL_DATA_LINK_L_PROTOCOL);
			TlvTree_AddChildInteger(hDataLinkConfig, LL_HDLC_T_MIN_RESEND_REQUESTS, 2, LL_HDLC_L_MIN_RESEND_REQUESTS);
			}

		if(CurrentConfig->m_bUsePpp)
			{
			TlvTree_AddChildInteger(hDataLinkConfig, LL_DATA_LINK_T_PROTOCOL, LL_DATA_LINK_V_PPP, LL_DATA_LINK_L_PROTOCOL);
			TlvTree_AddChildString(hDataLinkConfig, LL_PPP_T_LOGIN, CurrentConfig->m_szLogin);
			TlvTree_AddChildString(hDataLinkConfig, LL_PPP_T_PASSWORD, CurrentConfig->m_szPassword);
			}
		}
	//===========================================================================
	// 3rd set transport layer
	if(CurrentConfig->m_bUseTcpIp)
		{
		hTransportConfig = TlvTree_AddChild(hConfig, 
			                                LL_TAG_TRANSPORT_LAYER_CONFIG,  // TAG Transport layer parameters
											NULL,                           // VALUE (Null)
											0);                             // LENGTH 0

		if(hTransportConfig == NULL)
			{
			TlvTree_Release(hConfig);
			return cmmErrInitFailed;
			}
											
		TlvTree_AddChildInteger(hTransportConfig, LL_TRANSPORT_T_PROTOCOL, LL_TRANSPORT_V_TCPIP, LL_TRANSPORT_L_PROTOCOL);
		TlvTree_AddChildString(hTransportConfig, LL_TCPIP_T_HOST_NAME, CurrentConfig->m_szHostName);
		TlvTree_AddChildInteger(hTransportConfig, LL_TCPIP_T_PORT, CurrentConfig->m_nPort, LL_TCPIP_L_PORT);
		TlvTree_AddChildInteger(hTransportConfig, LL_TCPIP_T_CONNECT_TIMEOUT, CurrentConfig->m_nConnectionTimeout, LL_TCPIP_L_CONNECT_TIMEOUT);
		}


	nError = LL_Configure(cmmSession, hConfig);
//	xx_printf("nError : %d", nError);
	if(nError)
		{
//		TlvTree_Release(hTransportConfig);
//		TlvTree_Release(hDataLinkConfig);
//		TlvTree_Release(hPhysicalConfig);
		TlvTree_Release(hConfig);
		return cmmErrInitFailed;
		}

//	TlvTree_Release(hTransportConfig);
//	TlvTree_Release(hDataLinkConfig);
//	TlvTree_Release(hPhysicalConfig);
	TlvTree_Release(hConfig);

	return cmmSuccess;
										
}
#endif

//cmmResult_t cmmInit(uint32* deviceHandle,INIT_COMMS_PARAMS *icp)
cmmResult_t cmmInit(uint32* deviceHandle,INIT_COMMS_PARAMS *icp, bits32 predial)
{
	uint32 indx;
//	int nError;
//	_DEL_ pDel;

//	if(nvmCommsDeviceGet()==cmmDeviceGPRS)
//	{
//		if(cmmGPRSInit(deviceHandle, icp, predial)!=cmmSuccess)
//			return cmmErrInitFailed;
//		return cmmSuccess;
//	}


	cmmRetVal = cmmSuccess;//aan, 15 Juli 2007

	ThreadHandle = NULL;

	cmmMode = 0;
_trace("cmm Init dev  %d",*deviceHandle);
_trace("cmm InitA  %d",icp->cmmmode);
	if(*deviceHandle == 0)
	{ _trace("device 0");
		InitDefaultConfig();
		indx=getcombufempty();
		if (indx<0)
			{
			_trace("get com buf fail");
			return cmmErrInitFailed;
			}
			
		
		*deviceHandle=indx+1;
//	}
//	else
//		indx = *deviceHandle - 1;
_trace("cmm Init  %d",icp->cmmmode);
	cmmMode = icp->cmmmode;
	switch(icp->cmmmode)
	{
		case cmmDeviceNAC:
			//ConfigureHdlc(icp,indx,TRUE);
			ConfigureHdlc(icp,indx,DialPrimary);
			break;
		case cmmDeviceModem:
			//ConfigureModem(icp,indx,TRUE);
			ConfigureModem(icp,indx,DialPrimary);
			break;
		case cmmDeviceRS232:
			ConfigureComUSB(icp,indx,FALSE);
			break;
		case cmmDeviceUSB:
			ConfigureComUSB(icp,indx,TRUE);
			break;
		case cmmDeviceEthClient:
			//ConfigureTCP(icp,indx,TRUE);
			
			ConfigureTCP(icp,indx,DialPrimary);
			break;
		case cmmDevicePPP:
			//ConfigurePPP(icp,indx,TRUE);			
			ConfigurePPP(icp,indx,DialPrimary);			
			break;
		case cmmDeviceGPRS:
			//ConfigureTCP(icp,indx,TRUE);
			ConfigureTCP(icp,indx,DialPrimary);
			ConfigureGPRS(icp,indx,TRUE);
			break;

#ifdef _SSL_ENABLE_

		case cmmDeviceSSL:
			cmmSslConfigure(icp, DialPrimary);
			break;

#endif
			
	}

_trace("cmm Init2  %d",icp->cmmmode);

#ifdef _SSL_ENABLE_
	if(icp->cmmmode != cmmDeviceSSL)
#endif

	if(cmmConfigure(&cominfo[indx].CurrentConfig, &cominfo[indx].hSession) != cmmSuccess)
		return cmmErrInitFailed;
	
	}
	else
		indx = *deviceHandle - 1;
//aan
//before sending clear the send and/or receiption buffer
#ifdef _SSL_ENABLE_
	if(icp->cmmmode != cmmDeviceSSL)
#endif

	cmmFlushComBuffer(indx + 1, FLUSH_SEND_BUFFER | FLUSH_RECV_BUFFER);
//aan


#ifndef WIN32
	//aan
	//save comm handle index
	cmmIndx=indx;
	//save dialling mode
	predialState = predial;
	
	if(predial)//background dial use thread
	{
		_trace("predial mode");
		//init threadHandle
		if(ThreadHandle != NULL)
		{
			kill(ThreadHandle, "");
//			kill(ThreadHandle, "-*");
			ThreadHandle = NULL;
		}
		//initialize thread flag
		iThreadTerminate = FALSE;
		//get main task number
		MainTask = CurrentTask();

#ifdef _SSL_ENABLE_
		if(icp->cmmmode == cmmDeviceSSL)
			ThreadHandle = fork((PFONCFORK)cmmSslConnect, NULL,0);
		else
#endif
		ThreadHandle=(t_topstack *)fork((PFONCFORK)cmmConnect,(unsigned char *)&protocole_stack[PROTOCOLE_STACK_SIZE], 800);
		
		if(ThreadHandle == NULL)//fail to create thread
			return cmmErrDialBusy;

//		if(cmmRetVal != cmmSuccess)//fail to establish a connection
//			{
			//cmmEnd(cmmIndx + 1);
//			return cmmErrDialBusy;
//			}
	}
	else
	{
		//aan, check if before this we use predial mode
		//n then we must reconnect, make sure we kill the thread
		if(ThreadHandle != NULL)
		{
			kill(ThreadHandle, "");
//			kill(ThreadHandle, "-*");
			ThreadHandle = NULL;
		}
		_trace("non predial mode");
		_trace("connection %d",retvalini);

#ifdef _SSL_ENABLE_
		if(icp->cmmmode == cmmDeviceSSL)
		{
			_trace("SSL Connect");
			return cmmSslConnect();
		}
		else
#endif
		return cmmConnect();

		//aan
		//if(cmmConnect()!= cmmSuccess)
		//	return cmmErrDialBusy;
		}
	//aan
#else
_trace("connection %d",retvalini);

#ifdef _SSL_ENABLE_
	if(icp->cmmmode != cmmDeviceSSL)
#endif
	cmmRetVal=cmmLastErr(LL_Connect(cominfo[indx].hSession));


	return cmmRetVal;
	//nError=LL_Connect(cominfo[indx].hSession);

	//if (nError!=LL_ERROR_OK)
	//	if(nError != LL_ERROR_TIMEOUT)
	//		return cmmErrDialBusy;
#endif


	return cmmSuccess;
}

#if 0	//obsolete
cmmResult_t cmmEnd(uint32 deviceHandle)
{	

	int16 stt;

#ifndef WIN32
	//wait for 500 ms, after disconnect
	//ttestall(0,50);
	//kill the thread
	if((ThreadHandle != NULL)&&(predialState))
		{
		while(!iThreadTerminate)
			pp_ttestall(0, 1);

		kill(ThreadHandle, "");
//		kill(ThreadHandle, "-*");
		ThreadHandle = NULL;
		}
#endif

	if(cmmStatus(deviceHandle)!=LL_STATUS_DISCONNECTED)
		{
		LL_Disconnect(cominfo[deviceHandle-1].hSession);
		do
			{
				stt=cmmStatus(deviceHandle);
			}while((stt == LL_STATUS_DISCONNECTING) ||(stt != LL_STATUS_DISCONNECTED));
		}

	//instead we set NULL the hSession, we reconfigure it using NULL par
	//test aan
//	if((nvmCommsDeviceGet()!=cmmDeviceGPRS)||(nvmTMSConnectionGet()==))
		{
		if(LL_Configure(&cominfo[deviceHandle-1].hSession, NULL) == LL_ERROR_OK)
			cominfo[deviceHandle-1].hSession = NULL;
		}
/*
#ifndef WIN32
	//wait for 500 ms, after disconnect
	ttestall(0,50);
	//kill the thread
	if((ThreadHandle != NULL)&&(predialState))
		{
		while(!iThreadTerminate)
			ttestall(0, 1);

		//kill(ThreadHandle, "");
		kill(ThreadHandle, "-*");
		ThreadHandle = NULL;
		}
#endif
*/
	return cmmSuccess;
}
#else

void killthread(void)
{
#ifndef WIN32
	//wait for 500 ms, after disconnect
	//ttestall(0,50);
	//kill the thread
	
	

	if((ThreadHandle != NULL)&&(predialState))
		{		
		_trace("kill thread");
		
		
		
		while (!iThreadTerminate) 
		{
			
			if (pp_ttestall(KEYBOARD, 2)==KEYBOARD)
				{
					switch(GET_CHAR())
						{
								case T_ANN:
								case T_CORR:
								case VK_CANCEL:
								case VK_CLEAR:
									iThreadTerminate=TRUE;
									break;
						}
				}
			
		}
		
		kill(ThreadHandle, "");
//		kill(ThreadHandle, "-*");
		ThreadHandle = NULL;
		}
#endif
}
//24 Juli 2008, new Algorithm
cmmResult_t  cmmEnd(uint32 deviceHandle)
{	
	//int16 stt;
	uint8 tforce=FALSE;

	_trace("nvmDisconnectAlgorithmGet");
	
	
	//(nvmDisconnectAlgorithmGet() == ALGORITHM_DISCONNECT_FIRST)
	if (!iThreadTerminate)
		{
	
	
		 tforce=TRUE;
		 pp_ttestall(0, 50);
		if (cominfo[deviceHandle-1].hSession)
			LL_Disconnect(cominfo[deviceHandle-1].hSession);
		
			_trace("LL_Disconnect Done");
		if (LL_Configure(&cominfo[deviceHandle-1].hSession, NULL) == LL_ERROR_OK)
			cominfo[deviceHandle-1].hSession = NULL;
		
		iThreadTerminate=TRUE;
		}
	

	
	killthread();
	

	//if(nvmDisconnectAlgorithmGet() == ALGORITHM_KILL_THREAD_FIRST)
	if (!tforce)
		{
		//if(cmmStatus(deviceHandle)!=LL_STATUS_DISCONNECTED)
		//	{
		

				if (cominfo[deviceHandle-1].hSession)
				{
					LL_Disconnect(cominfo[deviceHandle-1].hSession);				

//					do
//					{
//						stt=cmmStatus(deviceHandle);
//					}while((stt == LL_STATUS_DISCONNECTING) ||(stt != LL_STATUS_DISCONNECTED));
					
					if (LL_Configure(&cominfo[deviceHandle-1].hSession, NULL) == LL_ERROR_OK)
						cominfo[deviceHandle-1].hSession = NULL;
				}
//			}
		}


	//if(LL_Configure(&cominfo[deviceHandle-1].hSession, NULL) == LL_ERROR_OK)

	//cominfo[deviceHandle-1].hSession = NULL;


	return cmmSuccess;
}

#endif

int16 cmmSend(uint32 deviceHandle, uint8 const* msg, size_t length)
{
	int bSend,n;
	uint16 nError;
	uint16 tm;
	
	n=length;
	//_trace_DSP2("msgsend ", (uint8 *)msg, length);
	LL_ClearSendBuffer(cominfo[deviceHandle-1].hSession);	// nazar, clear the buffer before send
	while (n>0)
	{		
		
			
		if (cominfo[deviceHandle-1].hSession==NULL)
			return cmmErrInitFailed;
		
//			bSend =  LL_Send(cominfo[deviceHandle-1].hSession, n, msg, 100); //15
			bSend =  LL_Send(cominfo[deviceHandle-1].hSession, n, msg, 280); //15

			if( bSend >= 0 )
			{
				n-=bSend;
			}
			else
			{
				nError = LL_GetLastError(cominfo[deviceHandle-1].hSession);
				return nError;
			}
		
		tm=ttestall(KEYBOARD, 1);		
			if (tm & KEYBOARD)
			{
				if (kbdRead()==(char)VK_CANCEL)
					return cmmErrUserCancel;
			}
		/*	
		*/
			
//aan
		//	LL_WaitEvent(cominfo[deviceHandle-1].hSession, LL_WAIT_SEND_END, LL_INFINITE);
//aan
		}

	return cmmSuccess;
}


int comRecBufModem(uint32 deviceHandle, uint8* msg, uint16* len, size_t maxSize)
{
	// Local variables 
	// ***************
	int ret, length=0, sec, nbrBytes;
	int length2 = *len;
	// Timeout setting
	// ***************
	sec = 500;

	if (cominfo[deviceHandle-1].hSession==NULL)
		return cmmErrInitFailed;

	// Clear receiving buffer
	// **********************
	ret = LL_ClearReceiveBuffer(cominfo[deviceHandle-1].hSession);

	// Receiving first block
	// *********************
	_trace("Modem Ready Receiving..........");
	nbrBytes = LL_Receive(cominfo[deviceHandle-1].hSession, maxSize, &msg[length], sec);
	length+=nbrBytes;

	_trace("Modem Checking Error..........");
	ret = LL_GetLastError(cominfo[deviceHandle-1].hSession);	
	_trace("Modem Receiving Err = %d..........", ret);
	if (nbrBytes != 0)
	{
		_trace("nbrbytes= %d..........", nbrBytes);
		// Receiving next block until timeout (Inter block 20ms)
		// =====================================================
		while(1)
		{
			nbrBytes = LL_Receive(cominfo[deviceHandle-1].hSession, length2 -length, &msg[length], 20);
			length+=nbrBytes;
			ret = LL_GetLastError(cominfo[deviceHandle-1].hSession);
			if (ret==LL_ERROR_TIMEOUT)
				break;
			if (nbrBytes == 0)
				break;
		}
	}
	_trace("nbrbytes2= %d..........", nbrBytes);
	*len = length2;
	ret = length;
    	return ret;
}

int16 cmmRecv(uint32 deviceHandle, uint8* msg, uint16* length, size_t maxSize)
{
	//add new variable to support new algorithm
	uint8 rxEnd = FALSE;
	
	int lastErr,i;

#ifdef __TEST_COMM_RX__	//aan
	uint16 len;

	*length = 0;
#endif

	
#if 1 //def __TEST_COMM_RX__ //aan
	i=0;
	do{
/*
		len = 0;
		len = (uint16)LL_Receive(cominfo[deviceHandle-1].hSession, maxSize, &msg[*length], 10); // tdnya nilai timeoutnya 10
		*length += len;
		lastErr=LL_GetLastError(cominfo[deviceHandle-1].hSession);
//		if (nvmTMSDebugGet())
//			Printf(0, "Last Err / len : %d", lastErr);
		if(lastErr != LL_ERROR_OK)
			return cmmErrGeneral;
*/


		//new algorithm to speed up the dial up process
		if (cominfo[deviceHandle-1].hSession==NULL)
			return cmmErrInitFailed;

		_trace("LL Receiving..........");
		len = (uint16)LL_Receive(cominfo[deviceHandle-1].hSession, maxSize, msg, 280); //280); // tdnya nilai timeoutnya 10

		_trace("LL Receiving %d Bytes", len);

		lastErr=LL_GetLastError(cominfo[deviceHandle-1].hSession);
		if(len > 0)
			{
			*length += len;
			rxEnd = TRUE;
			}

			if (lastErr == LL_ERROR_OK)
				continue;
			
			if (LL_ERROR_TIMEOUT==lastErr)
			{
				if (i<3)
				{
					i++;
					continue;
				}
				else
					return cmmErrUserTimeout;
			}
			else 
				return cmmErrGeneral;

		}while(!rxEnd);//while(!len);//new algorithm
#else
	//*length = (uint16)LL_Receive(cominfo[deviceHandle-1].hSession, maxSize, msg, 100); // tdnya nilai timeoutnya 10
	for (i=0;i<3;i++)
	{
	*length = (uint16)LL_Receive(cominfo[deviceHandle-1].hSession, maxSize, msg, 70); // tdnya nilai timeoutnya 10
//aan
		lastErr=LL_GetLastError(cominfo[deviceHandle-1].hSession);
		if (LL_ERROR_TIMEOUT!=lastErr)
			break;
	}	
//	if (nvmTMSDebugGet())
//		Printf(0, "Last Err / len : %d", lastErr);
	if(lastErr != LL_ERROR_OK)
		return cmmErrGeneral;
//aan
#endif

	return cmmSuccess;
}

int16 cmmListen(uint32 deviceHandle)
{
	int listenRetval = 0;
	if((listenRetval=LL_WaitEvent(cominfo[deviceHandle-1].hSession, LL_WAIT_RECEIVED_DATA, 6000))==0)//enfi "900->6000" 09082010
		return cmmLastErr(listenRetval);// cmmErrTimeout;
	return cmmSuccess;

	//return 0;
}
int16 cmmStatus(uint32 deviceHandle)
{
//aan
//	int lastErr;
//	lastErr=LL_GetLastError(cominfo[deviceHandle-1].hSession);
//	hex_dump("Status | LAST ERROR", &lastErr, sizeof(int));
//aan
	int Status =0;	

	if (cominfo[deviceHandle-1].hSession)
			Status = LL_GetStatus(cominfo[deviceHandle-1].hSession);
	else
			Status=LL_STATUS_DISCONNECTING;
/*
	//liat physical layer dulu
	switch(Status & LL_STATUS_LAYER_MASK)
		{
		case LL_STATUS_LAYER_GPRS:
			break;
		case LL_STATUS_LAYER_GSM:
			break;
		case LL_STATUS_LAYER_HDLC:
			break;
		case LL_STATUS_LAYER_PHYSICAL://modem
			break;
		case LL_STATUS_LAYER_PPP:
			break;
		case LL_STATUS_LAYER_TCPIP:
			break;
		}
*/
	return (Status & LL_STATUS_MASK);
}

int16 cmmGeneral(void)
{
	return 0;
}

int16 cmmDebug(char const* text, void const* buffer, size_t bufferLength)
{

	return 0;
}

int16 cmmPrintf(char const* format, ...)
{
	return 0;
}
int16 cmmTestMsg(const S_TRANSIN *msg)
{

	return 0;
}

//aan
void cmmFlushComBuffer(uint32 deviceHandle, uint8 buff2Clear)
{
//aan
//before sending clear the send buffer
	if((buff2Clear & FLUSH_SEND_BUFFER) && (cominfo[deviceHandle-1].hSession))			
		LL_ClearSendBuffer(cominfo[deviceHandle-1].hSession);
//aan

//aan
//before receive clear the receiption buffer
	if((buff2Clear & FLUSH_RECV_BUFFER) && (cominfo[deviceHandle-1].hSession))
		LL_ClearReceiveBuffer(cominfo[deviceHandle-1].hSession);
//aan
}
//aan

#if 1
/*
static uint8 uGPRSStart;
static t_topstack * GPRSThreadHandle;
static short GPRSMainTask;
static int IntmaxTimeOut;
static int retval;

void cmmGPRSThread(void)
{
	int nStatus, nError;
	
	retval = LL_GPRS_Connect(
							nvmAPNGet(), 
							nvmUserNameGet(), 
							nvmPasswordGet(), 
							IntmaxTimeOut);//nConnectTimo - nWaitTotal );//aan, 27 Juli 2007

	uGPRSStart=TRUE;
	SignalEvent(GPRSMainTask, 30);
//	do
//	{
//		nError = LL_Network_GetStatus( LL_PHYSICAL_V_GPRS, &nStatus);
//	}while(nStatus != LL_STATUS_GPRS_CONNECTED);
	ttestall(0,0);
}
*/
cmmResult_t cmmGPRS_Stop(void)
{
	LL_GPRS_Stop();
	return cmmSuccess;
}

cmmResult_t cmmGPRS_Start(uint8 gprsPredial, uint8 check)
{
	int nStatus=0, nError=0;
	int nConnectTimo, nWaitTotal;
	//aan, 27 Juli 2007
	int nMaxTimeOut;

#ifdef IMAM_COMMS
	char CommonMsg[5][25+1];
#endif
	
	cmmGPRS_Stop();

	if(!gprsPredial)
		{
		pp_display_clear(0);
		pp_display_text(3, 0, "START GPRS SERVICE", PT_ALIGN_CENTER|PT_CLEAR);
		}
	
		if((nError=LL_GPRS_Start((char*)"0000", nvmAPNGet()))==LL_ERROR_NETWORK_NOT_SUPPORTED)//this type of terminal doesn't support GPRS
		{
		Alarm(ALARM_WARNING);
		pp_display_text(1, 0, "THIS TERMINAL", PT_ALIGN_CENTER|PT_CLEAR);
		pp_display_text(2, 0, "DOESN'T SUPPORT", PT_ALIGN_CENTER|PT_CLEAR);
		pp_display_text(3, 0, "GPRS CONNECTION", PT_ALIGN_CENTER|PT_CLEAR);
		pp_get_key(2);
		return cmmErrSystem;
		}
	if (!check)
		nMaxTimeOut = 6000;//1500;//aan 27 Juli 2007
	else
		nMaxTimeOut = 1000;//niki pak niki yg minta ini
	
	nConnectTimo = 5; //30 detik//50 ms
	nWaitTotal=0;
	
	while((( nError = LL_Network_GetStatus( LL_PHYSICAL_V_GPRS, &nStatus )) == LL_ERROR_NETWORK_NOT_READY ) && 
		   ( nWaitTotal < nMaxTimeOut))//( nWaitTotal < nConnectTimo))//aan 27 Juli 2007
	{
		if( nStatus == LL_STATUS_GPRS_AVAILABLE )
		{
			if(!gprsPredial)
				{
				pp_display_text(2, 0, "ATTACH TO", PT_ALIGN_CENTER|PT_CLEAR);
				pp_display_text(3, 0, "GPRS CLOUD", PT_ALIGN_CENTER|PT_CLEAR);
				}
/*
			IntmaxTimeOut = nMaxTimeOut - nWaitTotal;
			uGPRSStart = FALSE;
			//init threadHandle
			if(GPRSThreadHandle != NULL)
			{
				//kill(ThreadHandle, "");
				kill(GPRSThreadHandle, "-*");
				GPRSThreadHandle = NULL;
			}
			//initialize thread flag
			//iThreadTerminate = FALSE;
			//get main task number
			GPRSMainTask = CurrentTask();
			GPRSThreadHandle=fork((PFONCFORK)cmmGPRSThread, NULL,0);
			if(GPRSThreadHandle == NULL)//fail to create thread
				{
				pp_display_clear(0);
				pp_display_text(1, 0, "FAIL TO ATTACH", PT_ALIGN_CENTER|PT_CLEAR);
				pp_display_text(2, 0, "TO GPRS CLOUD", PT_ALIGN_CENTER|PT_CLEAR);
				pp_display_text(3, 0, "PLS TRY AGAIN", PT_ALIGN_CENTER|PT_CLEAR);
				pp_get_key(2);
				return cmmErrDialBusy;
				}
*/				
		
				nError=LL_GPRS_Connect(nvmAPNGet(), 
							nvmUserNameGet(), 
							nvmPasswordGet(), 
							nMaxTimeOut - nWaitTotal );//nConnectTimo - nWaitTotal );//aan, 27 Juli 2007
									
/*
			while(1)
				{
					if(retval == LL_ERROR_TIMEOUT)
						{
						pp_display_clear(0);
						pp_display_text(1, 0, "FAIL TO ATTACH", PT_ALIGN_CENTER|PT_CLEAR);
						pp_display_text(2, 0, "TO GPRS CLOUD", PT_ALIGN_CENTER|PT_CLEAR);
						pp_display_text(3, 0, "PLS TRY AGAIN", PT_ALIGN_CENTER|PT_CLEAR);
						pp_get_key(1);
						kill(GPRSThreadHandle, "");
						GPRSThreadHandle = NULL;
						return cmmErrTimeout;
						}
					
					if(uGPRSStart == TRUE)
						{
						kill(GPRSThreadHandle, "");
						GPRSThreadHandle = NULL;
						break;
						}
					
					if( ttestall(KEYBOARD,1) != 0 )
					{
					switch(GET_CHAR())
						{
						case T_ANN:
						case T_CORR:
								{
								pp_display_clear(0);
								pp_display_text(1, 0, "FAIL TO ATTACH", PT_ALIGN_CENTER|PT_CLEAR);
								pp_display_text(2, 0, "TO GPRS CLOUD", PT_ALIGN_CENTER|PT_CLEAR);
								pp_display_text(3, 0, "PLS TRY AGAIN", PT_ALIGN_CENTER|PT_CLEAR);
								pp_get_key(2);
								kill(GPRSThreadHandle, "");
								GPRSThreadHandle = NULL;
								return cmmErrUserCancel;
								}
							break;
						}
					}
					nWaitTotal++;
				}
*/
			break;
			//return cmmSuccess;
		}
		else
		{
			ttestall( 0, nConnectTimo);
			nWaitTotal += nConnectTimo;
		}
	}
	if((nWaitTotal >= nMaxTimeOut)||(nError == LL_ERROR_TIMEOUT))
		{
			if (!check)
			{
				Alarm(ALARM_ERROR);
				pp_display_text(1, 0, "FAIL TO ATTACH", PT_ALIGN_CENTER|PT_CLEAR);
				pp_display_text(2, 0, "TO GPRS CLOUD", PT_ALIGN_CENTER|PT_CLEAR);
				pp_display_text(3, 0, "PLS TRY AGAIN", PT_ALIGN_CENTER|PT_CLEAR);
				pp_get_key(2);
			}
			return cmmErrUserTimeout;
		}
	
	if(nError != LL_ERROR_OK)
		{
			if (!check)
			{
				sprintf(CommonMsg[0], "UNKNOWN ERR : %d", nError);
				Alarm(ALARM_ERROR);
				pp_display_text(1, 0, "FAIL TO ATTACH", PT_ALIGN_CENTER|PT_CLEAR);
				pp_display_text(2, 0, "TO GPRS CLOUD", PT_ALIGN_CENTER|PT_CLEAR);
				pp_display_text(3, 0, CommonMsg[0], PT_ALIGN_CENTER|PT_CLEAR);
				pp_display_text(4, 0, "PLS TRY AGAIN", PT_ALIGN_CENTER|PT_CLEAR);
				pp_get_key(2);
			}
			return cmmErrSystem;
		}

	do
		{
		nError = LL_Network_GetStatus( LL_PHYSICAL_V_GPRS, &nStatus);
		}while(nStatus != LL_STATUS_GPRS_CONNECTED);

	if(!gprsPredial)
		{
		pp_display_text(2, 0, "ATTACHING", PT_ALIGN_CENTER|PT_CLEAR);
		pp_display_text(3, 0, "SUCCESS", PT_ALIGN_CENTER|PT_CLEAR);
		if (!check)
		{
			pp_get_key(2);
		}
		else
			pp_ttestall(KEYBOARD, 10);
		}
	return cmmSuccess;
}

cmmResult_t cmmGPRSInit(uint8 gprsPredial, uint8 check)
{
	return cmmGPRS_Start(gprsPredial,check);
}

//04012011
int cmmGetGPRSNetworkStatus(int *nStatus)
{
	return (LL_Network_GetStatus(LL_PHYSICAL_V_GPRS, nStatus));
}

#endif

//#ifdef __TEST_SEC_DIAL__
//cmmResult_t cmmLastErr(uint32 deviceHandle)
cmmResult_t cmmLastErr(int connRetval)
{
//	int iErr = 0;

//	iErr = LL_GetLastError(cominfo[deviceHandle-1].hSession);
//	if(nvmFlagCommsDebugGet())
//		Printf(0, "Last Err : %d",iErr);
	switch(connRetval)
	{
		case LL_ERROR_OK	://							0
		case LL_ERROR_ALREADY_CONNECTED://				(LL_ERRORS - 7)
		case LL_ERROR_DISCONNECTED	://				(LL_ERRORS - 8)
			break;
			
		//timeout, coba redial, kalo tidak bisa secondary
		// COMMON errors
		case LL_ERROR_TIMEOUT://						(LL_ERRORS - 4)
		//HDLC layer errors
		case LL_HDLC_ERROR_CONNECT_TIMEOUT://			(LL_HDLC_ERROR - 0)
			return cmmErrTimeout;

		//belum tersambung, coba redial, kalo tidak bisa coba secondary			
		//COMMON errors
		//case LL_ERROR_DISCONNECTED	://				(LL_ERRORS - 8)
		//case LL_ERROR_NOT_CONNECTED://					(LL_ERRORS - 6)
		//	return cmmErrDialNoTone;
		case LL_ERROR_BUSY://							(LL_ERRORS - 9)
		//MODEM layers errors
		case LL_MODEM_ERROR_RESPONSE_BUSY	://		(LL_MODEM_ERROR - 6)
			return cmmErrDialBusy;
			
		case LL_MODEM_ERROR_RESPONSE_NO_ANSWER://		(LL_MODEM_ERROR - 7)
		case LL_ERROR_NOT_CONNECTED:
			return cmmErrDialFailure;
			
		case LL_MODEM_ERROR_RESPONSE_NO_DIALTONE:
		//case LL_MODEM_ERROR_RESPONSE_NO_CARRIER://		(LL_MODEM_ERROR - 8)
			return cmmErrDialNoTone;
			
		case LL_MODEM_ERROR_RESPONSE_NO_CARRIER://		(LL_MODEM_ERROR - 8)
			return cmmErrDialNoCarrier;

		// TCP/IP layer errors
		case LL_ERROR_UNKNOWN_HOST:
			return cmmErrEthNoRemoteIpAddr;

			
		case LL_ERROR_CANNOT_CONNECT://					(LL_TCPIP_ERROR - 2)
		case LL_ERROR_CONNECTION_REFUSED://				(LL_TCPIP_ERROR - 3)
			return cmmErrEthHostConnectFail;
			
		case LL_ERROR_HOST_UNREACHABLE://				(LL_TCPIP_ERROR - 4)
		case LL_ERROR_NETWORK_UNREACHABLE://			(LL_TCPIP_ERROR - 5)
			return cmmErrEthInterfaceDown;

		//unknown errors
		// COMMON errors
		case LL_ERROR_UNKNOWN	://					(LL_ERRORS - 0)
		case LL_ERROR_UNKNOWN_CONFIG://					(LL_ERRORS - 1)
		case LL_ERROR_INVALID_HANDLE://					(LL_ERRORS - 2)
		case LL_ERROR_SERVICE_NOT_SUPPORTED://			(LL_ERRORS - 3)
		case LL_ERROR_INVALID_PARAMETER://				(LL_ERRORS - 5)
		default:
			return cmmErrGeneral;
	}
	return cmmSuccess;
}

void cmmSetDial(uint8 DialPri)
{
	DialPrimary = DialPri;
}

uint8 GetcmmSetDial(void)
{
	return DialPrimary;
}
//#endif


//aan, 15 Juli 2007
cmmResult_t cmmGetConnectionStatus(void)
{
	
	return cmmRetVal;
}

cmmResult_t cmmGetConnectionStatus2(uint32 deviceHandle)
{
	int iErr = 0;

	if (cominfo[deviceHandle-1].hSession)
		iErr = LL_GetLastError(cominfo[deviceHandle-1].hSession);
	else
		return cmmErrGeneral;

	_trace("LL_GetLastError %X",iErr);
	return cmmLastErr(iErr);
	//return cmmRetVal;
}
#endif


